package o2o.web.actions.order.other;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jinyou.utils.common.*;
import jPush.dao.JPushMessage;
import jxl.Workbook;
import jxl.write.Label;
import jxl.write.Number;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import lombok.extern.slf4j.Slf4j;
import map.AMapUtils;
import notice.dao.NoticeType;
import o2o.cache.agent.AgentOrderOverTimeMemory;
import o2o.cache.agent.CityAgentMemory;
import o2o.cache.company.postman.PostCompanyMemory;
import o2o.cache.order.*;
import o2o.cache.shop.ShopMemory;
import o2o.cache.tip.TipInfoPaotuiMemory;
import o2o.cache.user.UserAddressMemory;
import o2o.cache.user.UserAddressRecordMemory;
import o2o.cache.user.UserInfoMemory;
import o2o.cache.user.UserOnlineImpl;
import o2o.company.model.ShopInfo;
import o2o.config.dao.UserDaoSql;
import o2o.config.dao.utils.DaoUtils;
import o2o.config.dao.utils.Expression;
import o2o.config.dao.utils.Order;
import o2o.config.dao.utils.QueryCondition;
import o2o.dao.PO.PojoTables;
import o2o.dao.PO.agent.CityAgent;
import o2o.dao.PO.agent.OrderOverTimeInfo;
import o2o.dao.PO.company.postman.PostCompanyInfo;
import o2o.dao.PO.order.*;
import o2o.dao.PO.postman.POSTMAN_TYPE;
import o2o.dao.PO.sys.SYS_VARIABLE_PAOTUI;
import o2o.dao.PO.tip.TipInfoPaotui;
import o2o.dao.PO.user.UserAddress;
import o2o.dao.PO.user.UserAddressRecord;
import o2o.dao.PO.user.UserInfo;
import o2o.dao.PO.wallet.PAY_TYPE;
import o2o.dao.VO.agent.CityAgentVO;
import o2o.dao.VO.common.FileUploadInfo;
import o2o.dao.VO.order.OrderGameRulesVO;
import o2o.dao.VO.order.OtherOrderInfoVO;
import o2o.dao.VO.order.SpecialVO;
import o2o.dao.VO.sys.SysVariablePaotuiVO;
import o2o.service.order.other.OtherOrderService;
import o2o.system.data.PROMPTS;
import o2o.system.data.SYS_CONFIG_PATH;
import o2o.system.data.SYS_SETTINGS;
import o2o.thridpost.dada.controller.DadaCityController;
import o2o.thridpost.dada.controller.DadaOrderController;
import o2o.thridpost.dada.model.to.AddDadaOrderTO;
import o2o.utils.CommonUtils;
import o2o.utils.MultilingualResult;
import o2o.utils.OrderUtils;
import o2o.web.actions.agent.CityAgentMan;
import o2o.web.actions.notice.Notice;
import o2o.web.actions.order.OrderMan;
import o2o.web.actions.order.SubmitOrderMan;
import o2o.web.actions.order.thread.OrderThread;
import o2o.web.actions.sys.SysVariablePaotuiAction;
import o2o.web.actions.user.User;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import static o2o.web.actions.order.SubmitOrderMan.rollBackGoods;

//订单
@Controller
@Slf4j
public class OtherOrderAction {

    @Autowired
    private OtherOrderService otherOrderService;
    @Autowired
    private DadaOrderController dadaOrderController;
    @Autowired
    DadaCityController dadaCityController;

    // 发布频率限制 <收货地址Id，最后发布时间
    private ConcurrentHashMap<Long, Long> submitMap = new ConcurrentHashMap<>();

    //跑腿下单
    @RequestMapping(method = RequestMethod.POST, value = "/user/agent/post/submit", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String order_submit(String token, String sysAppKey, String lang, OtherOrderInfo info, Integer likePostmanAdvance, Double ridingDistance, String redpacketJson
            , String fromAddress2, String fromAddress3
            , String toAddress2, String toAddress3) throws Exception {

        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }
        // 地址
        String fromAddressStr = info.getFromAddress();
        Double fromLat = info.getFromLat();
        Double fromLng = info.getFromLng();
        String fromProv = info.getFromProvince();
        String fromCity = info.getFromCity();
        String fromCounty = info.getFromCounty();
        String fromUser = info.getFromUser();
        String fromPhone = info.getFromPhone();

        String toAddressStr = info.getToAddress();
        Double toLat = info.getToLat();
        Double toLng = info.getToLng();
        String toProv = info.getToProvince();
        String toCity = info.getToCity();
        String toCounty = info.getToCounty();
        String toUser = info.getToUser();
        String toPhone = info.getToPhone();

        if (ValidateUtil.isNull(info.getGoodsType())) {
            return MultilingualResult.errorResultV2(PROMPTS.ITEM_TYPE_EMPTY, lang);
        }
        // 判断省市区
//        if (ValidateUtil.isNotID(info.getFromId())) {
//            return MultilingualResult.errorResultV2(PROMPTS.SHIPMENT_NOT_EMPTY, lang);
//        }
        UserAddress fromAddress = null;
        if (ValidateUtil.isID(info.getFromId())) {
            fromAddress = UserAddressMemory.getInstance().getAddressInfo(info.getFromId());
            if (null == fromAddress) {
                return MultilingualResult.errorResultV2(PROMPTS.SHIP_INFORMATION_ERROR, lang);
            }
        } else {
            if (ValidateUtil.isNull(fromCity) || ValidateUtil.isNull(fromAddressStr) || ValidateUtil.isNotLatLng(fromLat, fromLng) || ValidateUtil.isNull(fromPhone)) {
                return MultilingualResult.errorResultV2(PROMPTS.SHIPMENT_NOT_EMPTY, lang);
            }
            fromAddress = new UserAddress();
            fromAddress.setAddress(fromAddressStr);
            fromAddress.setAddress2(fromAddress2);
            fromAddress.setAddress3(fromAddress3);
            fromAddress.setBuyer(fromUser);
            fromAddress.setTelephone(fromPhone);
            fromAddress.setProvince(fromProv);
            fromAddress.setCity(fromCity);
            fromAddress.setCounty(fromCounty);
            fromAddress.setLat(fromLat);
            fromAddress.setLng(fromLng);
        }
//        if (ValidateUtil.isNotID(info.getToId())) {
//            return MultilingualResult.errorResultV2(PROMPTS.DESTINATIONS_IS_EMPTY, lang);
//        }
        // 发送地
//        UserAddress fromAddress = UserAddressMemory.getInstance().getAddressInfo(info.getFromId());
//        if (null == fromAddress) {
//            return MultilingualResult.errorResultV2(PROMPTS.SHIP_INFORMATION_ERROR, lang);
//        }
        // 发送地
        UserAddress toAddress = null;
        if (ValidateUtil.isID(info.getToId())) {
            toAddress = UserAddressMemory.getInstance().getAddressInfo(info.getToId());
            if (null == toAddress) {
                return MultilingualResult.errorResultV2(PROMPTS.RECEIVING_ADDRESS_IS_INCORRECT, lang);
            }
        } else if (ValidateUtil.isID(info.getToId2())) {
            UserAddressRecord userAddressRecord = UserAddressRecordMemory.getInstance().getAddressInfo(info.getToId2());
            if (null == userAddressRecord) {
                return MultilingualResult.errorResultV2(PROMPTS.RECEIVING_ADDRESS_IS_INCORRECT, lang);
            }
            toAddress = new UserAddress();
            BeanUtils.copyProperties(userAddressRecord, toAddress);
        } else {
            if (ValidateUtil.isNull(toCity) || ValidateUtil.isNull(toAddressStr) || ValidateUtil.isNotLatLng(toLat, toLng) || ValidateUtil.isNull(toPhone)) {
                return MultilingualResult.errorResultV2(PROMPTS.DESTINATIONS_IS_EMPTY, lang);
            }
            toAddress = new UserAddress();
            toAddress.setAddress(toAddressStr);
            toAddress.setAddress2(toAddress2);
            toAddress.setAddress3(toAddress3);
            toAddress.setBuyer(toUser);
            toAddress.setTelephone(toPhone);
            toAddress.setProvince(toProv);
            toAddress.setCity(toCity);
            toAddress.setCounty(toCounty);
            toAddress.setLat(toLat);
            toAddress.setLng(toLng);
        }
        if (!ValidateUtil.isAbsDouble(ridingDistance)) {
            ridingDistance = 0.0d;
        }

        //根据发货地址 查找最近的代理
        if (ValidateUtil.isNull(fromAddress.getCity()) || ValidateUtil.isNotLatLng(fromAddress.getLat(), fromAddress.getLng())) {
            return MultilingualResult.errorResultV2(PROMPTS.ADDRESS_NOT_LOCATED, lang);
        }
        CityAgentVO cityAgentVO = CityAgentMan.getCityAgent(fromAddress.getCity(), fromAddress.getLat(), fromAddress.getLng());
        if (null == cityAgentVO) {
            return MultilingualResult.errorResultV2(PROMPTS.LOCATION_NOT_OPEN, lang);
        }
//        UserAddress toAddress = UserAddressMemory.getInstance().getAddressInfo(info.getToId());
//        if (null == toAddress) {
//            return MultilingualResult.errorResultV2(PROMPTS.RECEIVING_ADDRESS_IS_INCORRECT, lang);
//        }
        Double distance = 0.0d;
        if (SYS_SETTINGS.IS_RIDING_DISTANCE == 1) {
            distance = ValidateUtil.isAbsDouble(ridingDistance) ? ridingDistance : 0.0d;
        } else {
            distance = Geohash.distance(fromAddress.getLat(), fromAddress.getLng(), toAddress.getLat(), toAddress.getLng());
        }
        if (ValidateUtil.isAbsDouble(distance)) {
            ridingDistance = JYMathDoubleUtils.scaleHalfUp(JYMathDoubleUtils.div(distance, 1000));
        } else {
            ridingDistance = 0.0d;
        }

        Double disparityPrice = 0.0d;
        //是否要计算价格
        if (null != SYS_SETTINGS.PAOTUI_SYS_CAL_MONEY && 0 == 1 - SYS_SETTINGS.PAOTUI_SYS_CAL_MONEY) {
            //验证范围
            Double distinct = JYMathDoubleUtils.div(Geohash.distance(fromAddress.getLat(), fromAddress.getLng(), cityAgentVO.getLat(), cityAgentVO.getLng()), 1000);
            if (JYMathDoubleUtils.sub(distinct, cityAgentVO.getRang()) > 0) {
                return AjaxResult.errorResult("收货地址超出配送距离");
            }
            Double distinct2 = JYMathDoubleUtils.div(Geohash.distance(cityAgentVO.getLat(), cityAgentVO.getLng(), toAddress.getLat(), toAddress.getLng()), 1000);
            if (JYMathDoubleUtils.sub(distinct2, cityAgentVO.getRang()) > 0) {
                return AjaxResult.errorResult("收货地址超出配送距离2");
            }
            Double deliveryPrice = 0d;
            //获取商圈的配送费计算方式
            // Double distance = Geohash.distance(fromAddress.getLat(), fromAddress.getLng(), toAddress.getLat(), toAddress.getLng());
//            Double distance = 0.0d;
//            if (SYS_SETTINGS.IS_RIDING_DISTANCE == 1) {
//                distance = ValidateUtil.isAbsDouble(ridingDistance) ? ridingDistance : 0.0d;
//            } else {
//                distance = Geohash.distance(fromAddress.getLat(), fromAddress.getLng(), toAddress.getLat(), toAddress.getLng());
//            }
            if (null != distance) {
                // 如果设置比列  则按照比例计算距离
                if (SYS_SETTINGS.IS_RIDING_DISTANCE != 1 && SYS_SETTINGS.RUNNING_DISTANCE_RATE > 0) {
                    Double rate = JYMathDoubleUtils.div(SYS_SETTINGS.RUNNING_DISTANCE_RATE, 100);
                    distance = JYMathDoubleUtils.mul(distance, rate);
                }
                SysVariablePaotuiVO sysVariablePaotui = SysVariablePaotuiAction.infoOfAgentAndCode(cityAgentVO.getId(), SYS_VARIABLE_PAOTUI.PAO_TUI);
                if (null == sysVariablePaotui) {
                    return AjaxResult.errorResult("当前位置未开通");
                }
                Double km = JYMathDoubleUtils.div(distance, 1000);

                if (JYMathDoubleUtils.sub(km, Double.parseDouble(sysVariablePaotui.getRang())) <= 0) {
                    String money = sysVariablePaotui.getVal();
                    if (ValidateUtil.isNotNull(money)) {
                        deliveryPrice = Double.parseDouble(money);
                    }
                } else {
                    Double after = JYMathDoubleUtils.sub(km, Double.parseDouble(sysVariablePaotui.getRang()));
                    Double round = Math.ceil(after);
                    deliveryPrice = JYMathDoubleUtils.add(Double.parseDouble(sysVariablePaotui.getVal()), JYMathDoubleUtils.mul(round, Double.parseDouble(sysVariablePaotui.getPre())));
                }

                if (ValidateUtil.isAbsDouble(info.getDeliveryPrice())) {
                    disparityPrice = JYMathDoubleUtils.sub(deliveryPrice, info.getDeliveryPrice());
                }
                //配送费
                info.setDeliveryPrice(deliveryPrice);
            }
        }

        if (ValidateUtil.isNotAbsLong(info.getPickUpTime())) {
            info.setPickUpTime(0l);
        }

        if (SYS_SETTINGS.IS_SHOP_PAOTUI != 1 && ValidateUtil.isNotAbsDouble(info.getDeliveryPrice())) {
            return MultilingualResult.errorResultV2(PROMPTS.DELIVERY_FEE_IS_EMPTY, lang);
        }

        // 判断发布频率
        Long nowTime = DateUtils.getCurrTime();
        if (ValidateUtil.isID(info.getToId())) {
            if (submitMap.containsKey(info.getToId())) {
                Long lastTime = submitMap.get(info.getToId());
                if (ValidateUtil.isAbsLong(lastTime) && nowTime - lastTime < 60 * 1000) {// 1分钟内只能发布一次
                    return AjaxResult.errorResult("发布太快，请稍后再试");
                }
            }
            submitMap.put(info.getToId(), nowTime);
        }

        //1. 生成订单编号
        String orderNo = OrderUtils.getOrderNo();
        Long time = DateUtils.getCurrTime();

        info.setFromUser(fromAddress.getBuyer());
        info.setFromPhone(fromAddress.getTelephone());
        info.setFromProvince(fromAddress.getProvince());
        info.setFromCity(fromAddress.getCity());
        info.setFromCounty(fromAddress.getCounty());
        info.setFromLat(fromAddress.getLat());
        info.setFromLng(fromAddress.getLng());
        info.setFromAddress(fromAddress.getAddress()
                + (ValidateUtil.isNull(fromAddress.getAddress2()) ? "" : fromAddress.getAddress2())
                + (ValidateUtil.isNull(fromAddress.getAddress3()) ? "" : fromAddress.getAddress3()));

        info.setToUser(toAddress.getBuyer());
        info.setToPhone(toAddress.getTelephone());
        info.setToProvince(toAddress.getProvince());
        info.setToCity(toAddress.getCity());
        info.setToCounty(toAddress.getCounty());
        info.setToLat(toAddress.getLat());
        info.setToLng(toAddress.getLng());
        info.setToAddress(toAddress.getAddress()
                + (ValidateUtil.isNull(toAddress.getAddress2()) ? "" : toAddress.getAddress2())
                + (ValidateUtil.isNull(toAddress.getAddress3()) ? "" : toAddress.getAddress3()));
        OrderInfo orderInfo = new OrderInfo();

        Integer orders_status = ORDER_STATUS.SUBMIT;
        //3. 订单信息保存
        if (SYS_SETTINGS.IS_SHOP_PAOTUI != null && SYS_SETTINGS.IS_SHOP_PAOTUI == 1) {
            orders_status = ORDER_STATUS.PAYED;
            orderInfo.setIsShopPaoTuiOrder(1);
            orderInfo.setPayType(PAY_TYPE.UNDERLINE).setPayTime(DateUtils.getCurrTime());
            // 商家跑腿订单
            orderInfo.setTotalGoodsMoney(ValidateUtil.isAbsDouble(info.getGoodsPrice()) ? info.getGoodsPrice() : 0.0d);
        }
        info.setOrderStatus(orders_status);
        info.setTotalWeight(ValidateUtil.isAbsDouble(info.getTotalWeight()) ? info.getTotalWeight() : 0.0d);
//        orderInfo.setPayType(payType);
        info.setOrderNo(orderNo);
        info.setCreateTime(time);
        info.setCreateUser(user.getUsername());
        info.setDelFlag(0);
        info.setUsername(user.getUsername());
        if (ValidateUtil.isID(info.getCarTipId())) {
            TipInfoPaotui infoPaotui = TipInfoPaotuiMemory.getInstance().getById(info.getCarTipId());
            if (infoPaotui != null) {
                info.setCarTipName(infoPaotui.getName());
            }
        }
        info.setType(OtherOrderInfo.PAO_TUI);//跑腿

        //重量应该算到配送费里
        if (ValidateUtil.isAbsDouble(info.getWeightPrice()) && ValidateUtil.isAbsDouble(info.getDeliveryPrice())) {
            info.setDeliveryPrice(JYMathDoubleUtils.add(info.getDeliveryPrice(), info.getWeightPrice()));
        }

        //如果总金额为0则把配送费给总金额
        if (ValidateUtil.isNotAbsDouble(info.getTotalMoney())) {
            info.setTotalMoney(info.getDeliveryPrice());
        } else {
            // 计算一下差价
            if (null != SYS_SETTINGS.PAOTUI_SYS_CAL_MONEY && 0 == 1 - SYS_SETTINGS.PAOTUI_SYS_CAL_MONEY) {
                info.setTotalMoney(JYMathDoubleUtils.scaleHalfUp(JYMathDoubleUtils.add(info.getTotalMoney(), disparityPrice)));
            }
        }
//        OrderInfo orderInfo = new OrderInfo();
        // 0.0 一乙处理配送公司细信息
        // Set<Long> companyIdSet = new HashSet<>();

        Double totalMoney = info.getTotalMoney();
        Double mustPayMoney = totalMoney;
        Double awardMoney = 0.0d;
        Double platformAwardMoney = 0.0d;
        Double shopAwardMoney = 0.0d;
        try {
            UserDaoSql.getInstance().insertObj(PojoTables.OTHER_ORDER_INFO, info);
        } catch (SQLException e) {
            e.printStackTrace();
            submitMap.remove(info.getToId());
            return MultilingualResult.errorResultV2(PROMPTS.STORE_ORDER_INFORMATION_FAILED, lang);
        }

        //缓存中新增
        OtherOrderMemory.getInstance().addOrModify(orderNo);

        orderInfo.setOrderStatus(orders_status);
        orderInfo.setOrderType(ORDER_TYPE.PAO_TUI);//订单类型，跑腿订单
        orderInfo.setOrderNo(orderNo);
        orderInfo.setCreateTime(time);
        orderInfo.setCreateUser(user.getUsername());
        orderInfo.setDelFlag(0);
        orderInfo.setTotalPrice(mustPayMoney);
        //
        orderInfo.setAwardMoney(awardMoney);
        orderInfo.setShopAwardMoney(shopAwardMoney);
        orderInfo.setPlatformAwardMoney(platformAwardMoney);
        //

//        orderInfo.setTotalPrice(info.getTotalMoney());
        orderInfo.setTotalMoney(info.getTotalMoney());
        orderInfo.setTipMoney(info.getXiaofei());
        orderInfo.setDeliveryPrice(info.getDeliveryPrice());
        orderInfo.setUsername(user.getUsername());
        orderInfo.setCity(toAddress.getCity());
        orderInfo.setProvince(toAddress.getProvince());
        orderInfo.setCounty(toAddress.getCounty());
        orderInfo.setLat(toAddress.getLat());
        orderInfo.setLng(toAddress.getLng());
        orderInfo.setDeliveryId(toAddress.getId());
        orderInfo.setBuyer(toAddress.getBuyer());
        orderInfo.setTelephone(toAddress.getTelephone());
        orderInfo.setAddress(toAddress.getAddress()
                + (ValidateUtil.isNull(toAddress.getAddress2()) ? "" : toAddress.getAddress2())
                + (ValidateUtil.isNull(toAddress.getAddress3()) ? "" : toAddress.getAddress3()));
        orderInfo.setAddress2((ValidateUtil.isNull(toAddress.getAddress2()) ? "" : toAddress.getAddress2())
                + (ValidateUtil.isNull(toAddress.getAddress3()) ? "" : toAddress.getAddress3()));
        orderInfo.setTotalWeight(info.getTotalWeight());
        orderInfo.setDistance(ridingDistance);
        String address = "";
        if (ValidateUtil.isNotNull(fromAddress.getAddress())) {
            address = fromAddress.getAddress();
        }
        if (ValidateUtil.isNotNull(fromAddress.getAddress2())) {
            address += fromAddress.getAddress2();
        }
        if (ValidateUtil.isNotNull(fromAddress.getAddress3())) {
            address += fromAddress.getAddress3();
        }
        orderInfo.setShopAddress(address);
        orderInfo.setShopLat(fromAddress.getLat());
        orderInfo.setShopLng(fromAddress.getLng());
        orderInfo.setShopName(fromAddress.getBuyer());
        orderInfo.setShopCity(fromAddress.getCity());
        orderInfo.setShopPhone(fromAddress.getTelephone());
        orderInfo.setIsZiQu(0);
        orderInfo.setCarTipId(info.getCarTipId());
        orderInfo.setShopId(-2l);
        orderInfo.setZiQuTime(info.getPickUpTime());
        orderInfo.setIsComment(0);//是否已评价
        orderInfo.setUserDel(0);//是否已删除 0未删，1删除
        orderInfo.setIsUrgent(0);//是否加急
        orderInfo.setNote(info.getNote());//订单备注

        orderInfo.setAgentId(cityAgentVO.getId());
        if (likePostmanAdvance != null && likePostmanAdvance == 1 && orderInfo.getIsZiQu() == 0) {
            boolean isSpecifiedPostmen = SubmitOrderMan.isSpecifiedPostmen(orderInfo.getUsername(), orderInfo.getCity(), POSTMAN_TYPE.POSTMAN);
            if (isSpecifiedPostmen) {
                orderInfo.setIsSpecifiedPostmen(1);
            } else {
                orderInfo.setIsSpecifiedPostmen(0);
            }
        } else {
            orderInfo.setIsSpecifiedPostmen(0);
        }
        ShopInfo shopInfo = ShopMemory.getInstance().getShopByUsername(user.getUsername());
        boolean isThirdPart = false;
        // 1为开启第三方配送
        if (shopInfo != null && "1".equals(shopInfo.getThirdPartyType())) {
            // 达到多少公里
            String thirdPartyCond = shopInfo.getThirdPartyCond();
            // 第三方配送
            String thirdParty = shopInfo.getThirdParty();
            // 计算商家与买家的距离
            distance = Geohash.distance(fromLat, fromLng, toLat, toLng);
            // 如果大于, 甩给第三方配送
            if (distance > Integer.parseInt(thirdPartyCond) * 1000) {
                switch (thirdParty.toLowerCase()) {
                    case "dada":
                        log.info("满足第三方配送条件, 将把订单转发给达达配送, 订单号:{}", orderInfo.getOrderNo());
                        // 可以接单的配送公司
                        orderInfo.setOther_post_code("dada");
                        // 推送到第三方
                        orderInfo.setIsOtherPost(1);
                        // 查询城市代码
                        String cityResult = dadaCityController.queryCityCode(orderInfo.getCity());
                        JSONObject resultObj = JSONObject.parseObject(cityResult);
                        if (StringUtils.isNotEmpty(resultObj.getString("error"))) {
                            orderInfo.setOtherPostState(-1);
                            log.error("获取达达城市代码错误, city:{}", orderInfo.getCity());
                        } else {
                            String cityCode = resultObj.getJSONObject("info").getString("city_code");
                            log.error("获取达达城市代码:{}", cityCode);
                            // 添加达达订单
                            AddDadaOrderTO addDadaOrderTO = new AddDadaOrderTO(orderInfo, shopInfo, cityCode);
                            String orderResult = dadaOrderController.addOrderToDada(addDadaOrderTO);
                            JSONObject orderResultJson = JSONObject.parseObject(orderResult);
                            int status = orderResultJson.getInteger("status");
                            if (status == 0) {
                                log.error("添加达达订单失败, 原因:{}", orderResultJson.getString("error"));
                                orderInfo.setOtherPostState(-1);
                                return AjaxResult.errorResult("添加达达订单失败, 原因:" + orderResultJson.getString("error"));
                            } else {
                                log.error("添加达达订单成功");
                                orderInfo.setOtherPostState(1);
                                // 是否已同步给第三方 0未同步 1已同步
                                orderInfo.setIsSync2Tri(1);
                                // 是否取消或退款已同步给第三方 0未同步 1已同步
                                orderInfo.setIsRefundSync2Tri(0);
                                isThirdPart = true;
                            }
                        }
                        break;
                }
            }
        }
        // 如果是第三方配送不需要这些
        if (!isThirdPart) {
            // 配送时效
            if (shopInfo != null && StringUtils.isNotEmpty(shopInfo.getBaseHour()) && StringUtils.isNotEmpty(shopInfo.getPeakHour())) {
                String baseHour = shopInfo.getBaseHour();
                String peakHour = shopInfo.getPeakHour();
                String peakTimeBucket = shopInfo.getPeakTimeBucket();
                // 计算骑手配送时长
                int postmanOverTime = Integer.parseInt(StringUtils.isEmpty(baseHour) ? "0" : baseHour);
                if (StringUtils.isNotEmpty(peakTimeBucket)) {
                    JSONArray jsonArray = JSONObject.parseArray(peakTimeBucket);
                    SimpleDateFormat df = new SimpleDateFormat("HH:mm");
                    long createTime = orderInfo.getCreateTime();
                    String now = df.format(createTime);
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONArray array = jsonArray.getJSONArray(i);
                        if (DateUtils.isInTimeScope(now, array.getString(0), array.getString(1))) {
                            postmanOverTime += Integer.parseInt(StringUtils.isEmpty(peakHour) ? "0" : peakHour);
                            break;
                        }
                    }
                }
                // 设置骑手配送时长
                orderInfo.setAgentPostmanOverTime(postmanOverTime);
                // 设置订单即将超时提醒
                orderInfo.setAlertOrderTime(Integer.parseInt(shopInfo.getTimeoutRemind()));
            } else {
                // 配送时长问题
                OrderOverTimeInfo agentOrderOverTimeInfo = AgentOrderOverTimeMemory.getInstance().getAgentOrderOverTimeInfoByAgentId(orderInfo.getAgentId());
                if (null == agentOrderOverTimeInfo) {
                    agentOrderOverTimeInfo = AgentOrderOverTimeMemory.getInstance().getPlateDefaultSetting();
                }
                if (null != agentOrderOverTimeInfo) {
                    orderInfo.setAgentPostmanOverTime(agentOrderOverTimeInfo.getPostmanOverTime());
                    orderInfo.setAlertOrderTime(agentOrderOverTimeInfo.getAlertOrderTime());
                }
            }
            // 订单超时设置
            if (ValidateUtil.isID(orderInfo.getAgentId()) && SYS_SETTINGS.HAS_PAOTUI_ORDER_TIME_SET == 1) {
                // 配送时长问题
                OrderOverTimeInfo agentOrderOverTimeInfo = AgentOrderOverTimeMemory.getInstance().getAgentOrderOverTimeInfoByAgentId(orderInfo.getAgentId());
                if (null == agentOrderOverTimeInfo) {
                    agentOrderOverTimeInfo = AgentOrderOverTimeMemory.getInstance().getPlateDefaultSetting();
                }
                if (null != agentOrderOverTimeInfo) {
                    orderInfo.setAgentOrderOverTime(SubmitOrderMan.calculateOrderPsTime(agentOrderOverTimeInfo, ridingDistance));
                    orderInfo.setAgentNotTakenOrderTime(agentOrderOverTimeInfo.getNotTakenOrderTime());
                    orderInfo.setAgentPostmanAdvanceTime(agentOrderOverTimeInfo.getPostmanAdvanceTime());
                    orderInfo.setAlertPostmanTime(agentOrderOverTimeInfo.getAlertPostmanTime());
                    orderInfo.setPostmanBackOrderTime(agentOrderOverTimeInfo.getPostmanBackOrderTime());
                }
            }
        }

        try {
            UserDaoSql.getInstance().insertObj(PojoTables.OrderInfo, orderInfo);
        } catch (SQLException e) {
            e.printStackTrace();
            submitMap.remove(info.getToId());
            return MultilingualResult.errorResultV2(PROMPTS.STORE_ORDER_INFORMATION_FAILED, lang);
        }

        // 如果状态不是已经提交的状态的话  则直接调用更新的缓存
        if (orders_status - ORDER_STATUS.SUBMIT != 0) {
            OrderInfoMemory.getInstance().modifyStatus(orderNo);
        } else {
            OrderInfoMemory.getInstance().addOrderInfo(orderNo);
        }
        OrderInfoMemory.getInstance().create(orderInfo.getCreateTime());
        //4. 订单状态保存
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderNo(orderNo);
        orderStatus.setCreateUser(user.getUsername());
        orderStatus.setCreateTime(DateUtils.getCurrTime());
        orderStatus.setOrderStatus(orders_status);
        try {
            UserDaoSql.getInstance().insertObj(PojoTables.OrderStatus, orderStatus);
        } catch (SQLException e) {
            rollBackGoods(orderNo);
            e.printStackTrace();
            submitMap.remove(info.getToId());
            return MultilingualResult.errorResultV2(PROMPTS.STORE_ORDER_INFORMATION_FAILED, lang);
        }
        //5.3 缓存订单状态信息
        OrderStatusMemory.getInstance().addStatus(orderNo);

        if (orders_status - ORDER_STATUS.PAYED != 0) {
            //检测是否在规定时间内支付
            OrderInfo oInfo = OrderInfoMemory.getInstance().getOrderInfo(orderNo);
            OrderThread.map.put(orderNo, oInfo);

            //推送信息
            Notice.publishNotice2Person(sysAppKey, user.getUsername(), JPushMessage.USER, NoticeType.order, "订单信息", "您的跑腿订单已提交，请尽快支付");
        }

        // 更新常用地址次数
        if (SYS_SETTINGS.IS_SHOP_PAOTUI != null && SYS_SETTINGS.IS_SHOP_PAOTUI == 1) {
            if (ValidateUtil.isID(info.getToId())) {

            } else if (ValidateUtil.isID(info.getToId2())) {
                otherOrderService.updateReceivingAddressUsageTimes(info.getToId2(), 1);
            } else {
                otherOrderService.saveReceivingAddressRecord(toProv, toCity, toCounty, toAddressStr, toAddress2, toAddress3, toLat, toLng, user.getUsername(), info.getToUser(), info.getToPhone());
            }
        }
        return AjaxResult.successResult("orderNo", orderNo);
    }

    // 检查是否在指定范围内
    @RequestMapping(method = RequestMethod.POST, value = "/user/agent/address/check")
    @ResponseBody
    public String order_submit_person_tr(Long agentId, Double lat, Double lng) {
        if (ValidateUtil.isNotID(agentId)) {
            return AjaxResult.errorResult("出错了~~~");
        }
        if (ValidateUtil.isNotLatLng(lat, lng)) {
            return AjaxResult.errorResult("出错了~~~");
        }
        CityAgent cityAgent = CityAgentMemory.getInstance().getById(agentId);
        if (cityAgent == null) {
            return AjaxResult.errorResult("出错了~~~");
        }
        if (!CommonUtils.isInFenceRange(cityAgent.getLnglats(), lng, lat)) {
            return AjaxResult.errorResult("您选择的地点不在范围内");
        }
        return AjaxResult.successResult();
    }

    //获取跑腿或代购订单详情
    @RequestMapping(method = RequestMethod.POST, value = "/agent/order/info", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String order_info(String token, String orderNo) {
        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }

        if (ValidateUtil.isNull(orderNo)) {
            return AjaxResult.errorResult("请选择要查看的订单");
        }

        OtherOrderInfo info = OtherOrderMemory.getInstance().getByOrderNo(orderNo);
        if (null == info) {
            return AjaxResult.errorResult("未获取到相关信息，请稍后再试");
        }
        OtherOrderInfoVO infoVO = new OtherOrderInfoVO();
        try {
            ObjectUtils.copyPropertiesExclude(info, infoVO, null);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.errorResult("获取失败，请稍后再试.");
        }

        // 代购有特殊需求列表 返程费等
        if (infoVO.getType() == OtherOrderInfo.HUO_YUN) {
            List<SpecialVO> list = getListSpecialVOByOrderNo(orderNo);
            if (ValidateUtil.isAbsList(list)) {
                infoVO.setSpecialVOList(list);
            }
        }

        // 订单优惠
        List<OrderGameRulesVO> orderGameRulesVOList = listByOrderNO(orderNo);
        if (ValidateUtil.isAbsList(orderGameRulesVOList)) {
            infoVO.setGameAward(orderGameRulesVOList);
        }

        return AjaxResult.successResult(infoVO);
    }

    //用户获取跑腿订单列表
    @RequestMapping(method = RequestMethod.POST, value = "/user/paotui/order/list", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String userPaotui(String token, Integer type, Integer status, //  参考 USER_ORDER_FILTER
                             Long startTime, Long endTime, Integer isPostingCancel, // 是不是配送中取消的订单
                             Integer isTroubleOrder,    // 是不是异常订单
                             String orderNo, Integer page, Integer size) {
        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }
        log.info("用户信息:" + user.toString());
//        if (ValidateUtil.isNotAbsInteger(type)) {
//            return AjaxResult.errorResult("请选择要查看的类别");
//        }

        if (ValidateUtil.isNotAbsInteger(page)) {
            page = 1;
        }
        if (ValidateUtil.isNotAbsInteger(size)) {
            size = 10;
        }

        QueryCondition query = QueryCondition.getInstance();
        Expression expression = Expression.getInstance();
        if (null != type) {
            expression.addChild("type", type);
        }
        expression.addChild("delFlag", 0);
        expression.addChild("username", user.getUsername());
        expression.addChild("userDel", 0); // 用户未删除的
        if (status != null) {
            if (status - USER_ORDER_FILTER.ORDER_CANCEL == 0) {
                expression.addChild("orderStatus", Expression.OP_IN, StringUtils.join(ORDER_STATUS.userOrderCancelSet, ","));
                if (isPostingCancel != null && (isPostingCancel == 1 || isPostingCancel == 0)) {
                    expression.addChild("isPostingCancel", isPostingCancel);
                }
            }
            if (status - USER_ORDER_FILTER.WAITING_FOR_PICK == 0) {
                expression.addChild("orderStatus", Expression.OP_IN, StringUtils.join(ORDER_STATUS.userWaitForPickSet, ","));
            }
            if (status - USER_ORDER_FILTER.WAITING_FOR_POST == 0) {
                expression.addChild("orderStatus", Expression.OP_IN, StringUtils.join(ORDER_STATUS.userWaitForPostSet, ","));
            }
            if (status - USER_ORDER_FILTER.ORDER_FINISH == 0) {
                expression.addChild("orderStatus", Expression.OP_IN, StringUtils.join(ORDER_STATUS.finishDeliverSet, ","));
            }
        }
        // 是不是异常订单
        if (isTroubleOrder != null && isTroubleOrder == 1) {
            expression.addChild("isTroubleOrder", isTroubleOrder);
        }
        if (ValidateUtil.isAbsLong(startTime) && ValidateUtil.isAbsLong(endTime)) {
            expression.addChild("createTime", ">=", startTime).addChild("createTime", "<=", endTime);
        }
        if (ValidateUtil.isNotNull(orderNo)) {
            expression.addChild("orderNo", Expression.OP_LIKE, orderNo);
        }
        query.addCondition(expression);//所有未删除的
        query.setPage(page);
        query.setSize(size);
        List<Order> orders = new ArrayList<>();
        orders.add(new Order("createTime", Order.DESC));
        query.setOrders(orders);
        String sql = DaoUtils.getSql(PojoTables.OTHER_ORDER_INFO, query);
        String sqlCount = DaoUtils.getSqlCount(PojoTables.OTHER_ORDER_INFO, query);
        List<OtherOrderInfo> list = null;
        Long totalCount = 0l;
        log.info("sql语句：" + sqlCount);
        try {
            list = (List<OtherOrderInfo>) UserDaoSql.getInstance().list(OtherOrderInfo.class, sql);
            totalCount = UserDaoSql.getInstance().getCount(sqlCount);
        } catch (SQLException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("获取失败，请稍后再试");
        }
        if (!ValidateUtil.isAbsList(list)) {
            return AjaxResult.successResult(0, 0, null);
        }

        List<OtherOrderInfoVO> voList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (null == list.get(i)) {
                continue;
            }
            OtherOrderInfoVO infoVO = new OtherOrderInfoVO();
            BeanUtils.copyProperties(list.get(i), infoVO);
            if (ValidateUtil.isNull(infoVO.getCarTipName()) && ValidateUtil.isID(infoVO.getCarTipId())) {
                TipInfoPaotui infoPaotui = TipInfoPaotuiMemory.getInstance().getById(infoVO.getCarTipId());
                if (infoPaotui != null) {
                    infoVO.setCarTipName(infoPaotui.getName());
                }
            }
            // 获取订单详情
            if (null != list.get(i).getOrderNo()) {
                OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(list.get(i).getOrderNo());
                if (null != orderInfo) {
                    infoVO.setOrderStatus(orderInfo.getOrderStatus());
                    infoVO.setPostmanName(orderInfo.getPostmanName());
                    infoVO.setPreDayNo(orderInfo.getPreDayNo());
                    infoVO.setDistance(orderInfo.getDistance());
                }
            }
            // 货运订单
            if (infoVO.getType() == OtherOrderInfo.HUO_YUN) {
                List<SpecialVO> specialVOList = getListSpecialVOByOrderNo(infoVO.getOrderNo());
                if (ValidateUtil.isAbsList(specialVOList)) {
                    infoVO.setSpecialVOList(specialVOList);
                }
            }
            // 活动信息
            List<OrderGameRulesVO> orderGameRulesVOList = listByOrderNO(infoVO.getOrderNo());
            if (ValidateUtil.isAbsList(orderGameRulesVOList)) {
                infoVO.setGameAward(orderGameRulesVOList);
            }
            voList.add(infoVO);
        }


        if (!ValidateUtil.isAbsList(voList)) {
            return AjaxResult.successResult(0, 0, voList);
        }

        return AjaxResult.successResult(totalCount, voList.size(), voList);
    }

    private List<SpecialVO> getListSpecialVOByOrderNo(String orderNo) {

        if (ValidateUtil.isNotNull(orderNo)) {
            List<OrderGoods> orderGoodsList = OrderGoodsMemory.getInstance().listOfOrderNo(orderNo);
            if (ValidateUtil.isAbsList(orderGoodsList)) {
                List<SpecialVO> list = new ArrayList<>();
                for (OrderGoods orderGoods : orderGoodsList) {

                    if (orderGoods == null) {
                        continue;
                    }
                    list.add(new SpecialVO(orderGoods.getName(), orderGoods.getSpecs(), orderGoods.getGoodsPrice()));
                }
                if (ValidateUtil.isAbsList(list)) {
                    return list;
                }
            }
        }
        return null;
    }

    private List<OrderGameRulesVO> listByOrderNO(String orderNo) {
        if (!StringUtils.isEmpty(orderNo)) {
            List<OrderGameRules> orderGameRulesList = OrderGameMemory.getInstance().listOfOrderNo(orderNo);
            if (ValidateUtil.isAbsList(orderGameRulesList)) {
                List<OrderGameRulesVO> list = new ArrayList<>();
                for (OrderGameRules orderGameRules : orderGameRulesList) {
                    OrderGameRulesVO orderGameRulesVO = new OrderGameRulesVO();
                    try {
                        ObjectUtils.copyPropertiesExclude(orderGameRules, orderGameRulesVO);
                    } catch (Exception e) {
                        e.printStackTrace();
                        continue;
                    }
                    list.add(orderGameRulesVO);
                }
                return list;
            }
        }
        return null;
    }


    //---------------------------------------管理员

    //获取跑腿或代购订单列表
    @RequestMapping(method = RequestMethod.POST, value = "/agent/order/list")
    @ResponseBody
    public String order_list(String token, Long agentId, Integer type, String city, String county, Integer orderStatus,
                             Long carTipId, // 车型信息
                             Integer isStatus, // 后台显示状态（1进行中 2已完成 3退款订单）
                             String postman,
                             String orderNo,
                             Integer isPostingCancel,   // 是不是配送中取消的
                             Long startTime,
                             Long endTime,
                             Integer page, Integer size, Integer isExcel) {
        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }

        if (ValidateUtil.isNotAbsInteger(type)) {
            return AjaxResult.errorResult("请选择要查看的类别");
        }

        if (ValidateUtil.isNotAbsInteger(page)) {
            page = 1;
        }
        if (ValidateUtil.isNotAbsInteger(size)) {
            size = 10;
        }

        //判断用户类型
        if (!User.hasAdminAuth(user.getUserType())) {
            return AjaxResult.errorResult("您没有权限查看");
        }

        if (null == isExcel) {
            isExcel = 0;
        }
        if (null == isStatus) {
            isStatus = 0;
        }

        String toCity = "";
        String inAgentStr = "";
        String types = "";
        if (null != type) {
            types = " and o.type=" + type + " ";
        }
        String orderS = "";
        String orderSta = "";
        if (null != orderStatus && orderStatus > 0) {
            orderS = " and o.orderStatus=" + orderStatus + " ";
        } else {
            if (isStatus == 1) {
                // 进行中
                orderSta = " and o.orderStatus!=" + ORDER_STATUS.OVER +
                        " and o.orderStatus!=" + ORDER_STATUS.CANCEL +
                        " and o.orderStatus!=" + ORDER_STATUS.CANCEL_BY_SYSTEM +
                        " and o.orderStatus!=" + ORDER_STATUS.PAYED_CANCEL +
                        " and o.orderStatus!=" + ORDER_STATUS.SHOP_REFUSED +
                        " and o.orderStatus!=" + ORDER_STATUS.SUBMIT +
                        " and o.orderStatus!=" + ORDER_STATUS.PAYED + " ";
            }
            if (isStatus == 2) {
                // 已完成
                orderSta = " and o.orderStatus=" + ORDER_STATUS.OVER + " ";
            }
            if (isStatus == 3) {
                // 退款订单
                orderSta = " and (o.orderStatus=" + ORDER_STATUS.CANCEL +
                        " or o.orderStatus=" + ORDER_STATUS.PAYED_CANCEL +
                        " or o.orderStatus=" + ORDER_STATUS.PAYED_APPLY_PART_CANCEL +
                        " or o.orderStatus=" + ORDER_STATUS.PAYED_PASS_PART_CANCEL + " ) ";
                if (isPostingCancel != null && (isPostingCancel == 0 || isPostingCancel == 1)) {
                    orderSta += " and o.isPostingCancel = " + isPostingCancel;
                }
            }
        }
        String select = " select * ";
        String count = " select count(1) counts ";
        String sql = " from other_order_info as o " + " left join " + PojoTables.OrderInfo + " as a on o.OrderNo = a.orderNo where o.delFlag=0 " + inAgentStr + toCity + types + orderS + orderSta + " ";
        if (ValidateUtil.isID(agentId)) {
            sql += "and a.agentId =" + agentId + " ";
        }
        if (ValidateUtil.isID(carTipId)) {
            sql += "and a.carTipId =" + carTipId + " ";
        }
        if (ValidateUtil.isAbsLong(startTime) && ValidateUtil.isAbsLong(endTime)) {
            sql += " and o.createTime between " + startTime + " and  " + endTime + " ";
        } else {
            long pointTime = OrderMan.getDefaultQueryOrderTimePoint();
            sql += ValidateUtil.isAbsLong(pointTime) ? "and o.createTime >  " + pointTime + " " : "";
        }
        if (ValidateUtil.isNotNull(orderNo)) {
            sql += " and o.orderNo like '%" + orderNo + "%' ";
        }
        if (ValidateUtil.isNotNull(postman)) {
            sql += " and a.postManUsername like '%" + postman + "%' ";
        }
        String group = " group by o.orderNo order by o.createTime desc";
        String limit = " limit " + (page - 1) * size + "," + size;
        List<OtherOrderInfo> list = null;
        Long totalCount = 0l;
        try {
            String sqlSelect = select + sql + group + limit;
            String sqlCount = count + sql;
            list = (List<OtherOrderInfo>) UserDaoSql.getInstance().list(OtherOrderInfo.class, sqlSelect);
            totalCount = UserDaoSql.getInstance().getCount(sqlCount);

        } catch (SQLException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("获取失败，请稍后再试");
        }
        if (!ValidateUtil.isAbsList(list)) {
            return AjaxResult.successResult(0, 0, null);
        }

        List<OtherOrderInfoVO> voList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (null == list.get(i)) {
                continue;
            }
            OtherOrderInfoVO infoVO = new OtherOrderInfoVO();
            try {
                ObjectUtils.copyPropertiesExclude(list.get(i), infoVO, null);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
            if (ValidateUtil.isNull(infoVO.getCarTipName()) && ValidateUtil.isID(infoVO.getCarTipId())) {
                TipInfoPaotui infoPaotui = TipInfoPaotuiMemory.getInstance().getById(infoVO.getCarTipId());
                if (infoPaotui != null) {
                    infoVO.setCarTipName(infoPaotui.getName());
                }
            }
            // 获取订单详情
            if (null != list.get(i).getOrderNo()) {
                OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(list.get(i).getOrderNo());
                if (null != orderInfo) {
                    infoVO.setOrderStatus(orderInfo.getOrderStatus());
                    infoVO.setPostmanName(orderInfo.getPostmanName());
                    infoVO.setPreDayNo(orderInfo.getPreDayNo());
                    infoVO.setIsRefundApply(orderInfo.getIsRefundApply());
                }
            }
            //计算配送距离
            if (infoVO.getFromLat() != null && infoVO.getFromLng() != null && infoVO.getToLat() != null && infoVO.getToLng() != null) {
                String distinct = AMapUtils.getRideDistinct(infoVO.getFromLat(), infoVO.getFromLng(), infoVO.getToLat(), infoVO.getToLng());
                infoVO.setDistance(Double.valueOf(distinct) / 1000);
            }
            voList.add(infoVO);
        }

        if (isExcel == 1) {
            // 导出excel
            String downloadUrl = runOrderExcel(voList);
            if (ValidateUtil.isNotNull(downloadUrl)) {
                String url = SYS_CONFIG_PATH.IMAGE_BASE_URL + downloadUrl;
                return AjaxResult.successResult(url);
            }
        } else {
            if (ValidateUtil.isAbsList(voList)) {
                return AjaxResult.successResult(totalCount, voList.size(), voList);
            }
        }
        return AjaxResult.successResult(0, 0, voList);
    }

    //获取跑腿或代购订单列表
    @RequestMapping(method = RequestMethod.POST, value = "/company/paotui/order/list")
    @ResponseBody
    public String paotui_order_list(String token, Long companyId, Integer type,
                                    String city,
                                    Integer orderStatus,
                                    Long carTipId, // 车型信息
                                    Integer isStatus, // 后台显示状态（1进行中 2已完成 3退款订单）
                                    Integer page, Integer size, Integer isExcel) {
        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }

        if (ValidateUtil.isNotID(companyId)) {
            PostCompanyInfo companyInfo = PostCompanyMemory.getInstance().getByUsername(user.getUsername());
            if (companyInfo == null) {
                return AjaxResult.errorResult("公司信息不能为空");
            }
            companyId = companyInfo.getId();
        }

        if (ValidateUtil.isNotAbsInteger(type)) {
            return AjaxResult.errorResult("请选择要查看的类别");
        }

        if (ValidateUtil.isNotAbsInteger(page)) {
            page = 1;
        }
        if (ValidateUtil.isNotAbsInteger(size)) {
            size = 10;
        }

        if (null == isExcel) {
            isExcel = 0;
        }
        if (null == isStatus) {
            isStatus = 0;
        }

        String toCity = "";
        if (ValidateUtil.isNotNull(city)) {
            toCity = " and o.toCity='" + city + "' ";
        }
        // if (User.hasSuperAdminAuth(user.getUserType())) {
        //     if (ValidateUtil.isNotNull(city)) {
        //         toCity = " and o.toCity='" + city + "' ";
        //     }
        // } else {
        //     //如果是普通管理员 那么只能看他所在城市的订单
        //     //管理员所在城市
        //     List<SysCityAdmin> list = SysCityAdminMemory.getInstance().listOfUsername(user.getUsername());
        //     if (ValidateUtil.isAbsList(list) && null != list.get(0)) {
        //         toCity = " and o.toCity='" + list.get(0).getCity() + "' ";
        //     }
        // }
        String types = "";
        if (null != type) {
            types = " and o.type=" + type + " ";
        }
        String orderS = "";
        String orderSta = "";
        if (null != orderStatus && orderStatus > 0) {
            orderS = " and o.orderStatus=" + orderStatus + " ";
        } else {
            if (isStatus == 1) {
                // 进行中
                orderSta = " and o.orderStatus!=" + ORDER_STATUS.OVER +
                        " and o.orderStatus!=" + ORDER_STATUS.CANCEL +
                        " and o.orderStatus!=" + ORDER_STATUS.CANCEL_BY_SYSTEM +
                        " and o.orderStatus!=" + ORDER_STATUS.PAYED_CANCEL +
                        " and o.orderStatus!=" + ORDER_STATUS.SHOP_REFUSED +
                        " and o.orderStatus!=" + ORDER_STATUS.SUBMIT +
                        " and o.orderStatus!=" + ORDER_STATUS.PAYED + " ";
            }
            if (isStatus == 2) {
                // 已完成
                orderSta = " and o.orderStatus=" + ORDER_STATUS.OVER + " ";
            }
            if (isStatus == 3) {
                // 退款订单
                orderSta = " and (o.orderStatus=" + ORDER_STATUS.CANCEL +
                        " or o.orderStatus=" + ORDER_STATUS.PAYED_CANCEL +
                        " or o.orderStatus=" + ORDER_STATUS.PAYED_APPLY_PART_CANCEL +
                        " or o.orderStatus=" + ORDER_STATUS.PAYED_PASS_PART_CANCEL + " ) ";
            }
        }
        String companyIds = " AND (grabCompanyId = " + companyId + " or (find_in_set(" + companyId + ",canGrabCompanyIds)and grabCompanyId is null))";
        String select = " select * ";
        String count = " select count(1) counts ";
        String sql = " from other_order_info as o " + " left join " + PojoTables.OrderInfo + " as a on o.OrderNo = a.orderNo where o.delFlag=0 " + toCity + types + orderS + orderSta + companyIds + " ";

        if (ValidateUtil.isID(carTipId)) {
            sql += "and a.carTipId =" + carTipId + " ";
        }
        String group = " group by o.createTime desc";
        String limit = " limit " + (page - 1) * size + "," + size;
        List<OtherOrderInfo> list = null;
        Long totalCount = 0l;
        try {
            String sqlSelect = select + sql + group + limit;
            String sqlCount = count + sql;
            list = (List<OtherOrderInfo>) UserDaoSql.getInstance().list(OtherOrderInfo.class, sqlSelect);
            totalCount = UserDaoSql.getInstance().getCount(sqlCount);
        } catch (SQLException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("获取失败，请稍后再试");
        }
        if (!ValidateUtil.isAbsList(list)) {
            return AjaxResult.successResult(0, 0, null);
        }

        List<OtherOrderInfoVO> voList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (null == list.get(i)) {
                continue;
            }
            OtherOrderInfoVO infoVO = new OtherOrderInfoVO();
            BeanUtils.copyProperties(list.get(i), infoVO);
            if (ValidateUtil.isNull(infoVO.getCarTipName()) && ValidateUtil.isID(infoVO.getCarTipId())) {
                TipInfoPaotui infoPaotui = TipInfoPaotuiMemory.getInstance().getById(infoVO.getCarTipId());
                if (infoPaotui != null) {
                    infoVO.setCarTipName(infoPaotui.getName());
                }
            }
            // 获取订单详情
            if (null != list.get(i).getOrderNo()) {
                OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(list.get(i).getOrderNo());
                if (null != orderInfo) {
                    infoVO.setOrderStatus(orderInfo.getOrderStatus());
                    infoVO.setPostmanName(orderInfo.getPostmanName());
                    infoVO.setPreDayNo(orderInfo.getPreDayNo());
                }
            }
            voList.add(infoVO);
        }
        if (isExcel == 1) {
            // 导出excel
            String downloadUrl = runOrderExcel(voList);
            if (ValidateUtil.isNotNull(downloadUrl)) {
                String url = SYS_CONFIG_PATH.IMAGE_BASE_URL + downloadUrl;
                return AjaxResult.successResult(url);
            }
        } else {
            if (ValidateUtil.isAbsList(voList)) {
                return AjaxResult.successResult(totalCount, voList.size(), voList);
            }
        }
        return AjaxResult.successResult(0, 0, voList);
    }

    //获取跑腿或代购订单列表V2(根据城市代理管辖商圈获取)
    @RequestMapping(method = RequestMethod.POST, value = "/agent/run/order/list/v2")
    @ResponseBody
    public String order_list_v2(String token, Long agentId, Integer type, Integer orderStatus,
                                Long carTipId,  // 车型信息
                                Integer isStatus, // 后台显示状态（1进行中 2已完成 3退款订单）
                                Integer page, Integer size) {
        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }

        if (ValidateUtil.isNotAbsInteger(page)) {
            page = 1;
        }
        if (ValidateUtil.isNotAbsInteger(size)) {
            size = 10;
        }

        String orderStatusStr = "";
        if (ValidateUtil.isAbsInteger(orderStatus)) {
            orderStatusStr = " and a.orderStatus='" + orderStatus + "'";
        }
        String typeStr = "";
        if (null != type && type > 0) {
            typeStr = " and a.type = " + type;
        }
        if (null == isStatus) {
            isStatus = 0;
        }
        String orderSta = "";
        if (isStatus == 1) {
            // 进行中
            orderSta = " and a.orderStatus!=" + ORDER_STATUS.OVER +
                    " and a.orderStatus!=" + ORDER_STATUS.CANCEL +
                    " and a.orderStatus!=" + ORDER_STATUS.CANCEL_BY_SYSTEM +
                    " and a.orderStatus!=" + ORDER_STATUS.PAYED_CANCEL +
                    " and a.orderStatus!=" + ORDER_STATUS.SHOP_REFUSED +
                    " and a.orderStatus!=" + ORDER_STATUS.SUBMIT +
                    " and a.orderStatus!=" + ORDER_STATUS.PAYED + " ";
        }
        if (isStatus == 2) {
            // 已完成
            orderSta = " and a.orderStatus=" + ORDER_STATUS.OVER + " ";
        }
        if (isStatus == 3) {
            // 退款订单
            orderSta = " and (a.orderStatus=" + ORDER_STATUS.CANCEL +
                    " or a.orderStatus=" + ORDER_STATUS.PAYED_CANCEL +
                    " or a.orderStatus=" + ORDER_STATUS.PAYED_APPLY_PART_CANCEL +
                    " or a.orderStatus=" + ORDER_STATUS.PAYED_PASS_PART_CANCEL + ") ";
        }

        List<OtherOrderInfoVO> list = null;

        StringBuffer sb = new StringBuffer();
        sb.append(" from ").append(PojoTables.OTHER_ORDER_INFO)
                .append(" a LEFT JOIN ").append(PojoTables.OrderInfo).append(" b ON a.orderNo = b.orderNo ")
                .append(" LEFT JOIN ").append(PojoTables.USER_AGENT_RELATION).append(" c ON c.agentId = b.agentId")
                .append(" WHERE c.delFlag = 0 AND c.username ='").append(user.getUsername()).append("'")
                .append(orderStatusStr).append(typeStr).append(orderSta);
        if (ValidateUtil.isID(agentId)) {
            sb.append(" and b.agentId =").append(agentId);
        }
        if (ValidateUtil.isID(carTipId)) {
            sb.append(" and b.carTipId =").append(carTipId);
        }
        sb.append(" ORDER BY a.createTime DESC ");


        Long totalCount = 0l;
        try {
            StringBuffer sbSql = new StringBuffer();
            sbSql.append("SELECT a.*, b.agentId ").append(sb.toString()).append(" LIMIT ").append((page - 1) * size).append(",").append(size);
            list = (List<OtherOrderInfoVO>) UserDaoSql.getInstance().list(OtherOrderInfoVO.class, sbSql.toString());

            StringBuffer sbCount = new StringBuffer();
            sbCount.append("select count(1) counts ").append(sb.toString());
            totalCount = UserDaoSql.getInstance().getCount(sbCount.toString());
        } catch (SQLException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("查询失败，请稍后再试");
        }
        if (!ValidateUtil.isAbsList(list)) {
            return AjaxResult.successResult(0, 0, list);
        }
        List<OtherOrderInfoVO> voList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (null == list.get(i)) {
                continue;
            }
            OtherOrderInfoVO infoVO = new OtherOrderInfoVO();
            try {
                ObjectUtils.copyPropertiesExclude(list.get(i), infoVO, null);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
            // 获取订单详情
            OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(list.get(i).getOrderNo());
            if (null != orderInfo) {
                infoVO.setOrderStatus(orderInfo.getOrderStatus());
                infoVO.setOrderStatusName(OrderStatusNameMemory.getInstance().getStatusName(infoVO.getOrderStatus()));
                infoVO.setPostmanName(orderInfo.getPostmanName());
                infoVO.setPreDayNo(orderInfo.getPreDayNo());
                infoVO.setIsRefundApply(orderInfo.getIsRefundApply());
            }
            voList.add(infoVO);
        }
        if (ValidateUtil.isAbsList(voList)) {
            return AjaxResult.successResult(totalCount, voList.size(), voList);
        }
        return AjaxResult.successResult(0, 0, voList);
    }


    //标记跑腿代购订单已完成
    @RequestMapping(method = RequestMethod.POST, value = "/agent/order/finish")
    @ResponseBody
    public String order_finish(String token, Integer type, String orderNo) {
        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }

        if (ValidateUtil.isNull(orderNo)) {
            return AjaxResult.errorResult("请选择要标记的订单");
        }
        if (ValidateUtil.isNotAbsInteger(type)) {
            return AjaxResult.errorResult("请选择要标记的类别");
        }

        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(PojoTables.ORDER_SHOP_SPECS).append(" set orderStatus =").append(ORDER_STATUS.OVER)
                .append(",updateUser = '").append(user.getUsername()).append("' where delFlag = 0 and orderNo = '").append(orderNo).append("'");
        try {
            UserDaoSql.getInstance().executeBySql(sb.toString());
        } catch (SQLException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("标记失败，请稍后再试");
        }


        return AjaxResult.successResult();
    }


    // 跑腿订单导出excel
    //---------------------------------生成配送员订单统计Excel
    private String runOrderExcel(List<OtherOrderInfoVO> list) {
        if (!ValidateUtil.isAbsList(list)) {
            return null;
        }
        String outputPath = "";
        try {
            outputPath = SYS_CONFIG_PATH.ORDER_IMAGE + "/" + DateUtils.getCurrentYearMonth() + "/" + DateUtils.getCurrTime() + ".xls";

            File outputFile = new File(SYS_CONFIG_PATH.IMAGE_BASE_FILE + outputPath);
            FileUtils.forceMkdirParent(outputFile);

            WritableWorkbook workbook = Workbook.createWorkbook(outputFile);

//        workbook = Workbook.createWorkbook(outputFile, Workbook.getWorkbook(templateFile));

            // 生成名为"学生"的工作表，参数0表示这是第一页
            WritableSheet sheet = workbook.createSheet("sheet1", 0);

//        WritableSheet sheet = workbook.getSheet(0);
            jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#0.00");   // 设置数字格式
            jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf); // 设置表单格式
            int col = 0;   // 列
            int row = 0;  // 行
            sheet.addCell(new Label(col++, row, "订单编号"));
            sheet.addCell(new Label(col++, row, "订单创建时间"));
            sheet.addCell(new Label(col++, row, "订单状态"));
            sheet.addCell(new Label(col++, row, "物品类型"));

            sheet.addCell(new Label(col++, row, "重量"));
            sheet.addCell(new Label(col++, row, "取件时间"));
//            sheet.addCell(new Label(col++, row, "商品价格"));
            sheet.addCell(new Label(col++, row, "配送费"));

            sheet.addCell(new Label(col++, row, "发货人"));
            sheet.addCell(new Label(col++, row, "发货地址"));
            sheet.addCell(new Label(col++, row, "发货人电话"));

            sheet.addCell(new Label(col++, row, "发货人"));
            sheet.addCell(new Label(col++, row, "收货地址"));
            sheet.addCell(new Label(col++, row, "收货人电话"));

            sheet.addCell(new Label(col++, row, "配送员姓名"));
            sheet.addCell(new Label(col++, row, "配送员电话"));

            row = 1;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            for (OtherOrderInfoVO record : list) {
                col = 0;
                double totalPrice = 0;

                String creatTim = sdf.format(record.getCreateTime());
                String pickUpTime = record.getPickUpTime() > 0 ? sdf.format(record.getCreateTime()) : "";

                OrderInfo orderInfo = OrderInfoMemory.getInstance().getOrderInfo(record.getOrderNo());

                sheet.addCell(new Label(col++, row, record.getOrderNo()));
                sheet.addCell(new Label(col++, row, creatTim));
                sheet.addCell(new Label(col++, row, record.getOrderStatusName()));
                sheet.addCell(new Label(col++, row, record.getGoodsType()));

                sheet.addCell(new Label(col++, row, record.getWeight()));
                sheet.addCell(new Label(col++, row, pickUpTime));  // 取件时间
                sheet.addCell(new Number(col++, row, record.getDeliveryPrice()));

                sheet.addCell(new Label(col++, row, record.getFromUser()));
                sheet.addCell(new Label(col++, row, record.getFromAddress()));
                sheet.addCell(new Label(col++, row, record.getFromPhone()));
                sheet.addCell(new Label(col++, row, record.getToUser()));
                sheet.addCell(new Label(col++, row, record.getToAddress()));
                sheet.addCell(new Label(col++, row, record.getToPhone()));

                sheet.addCell(new Label(col++, row, null != orderInfo ? orderInfo.getPostmanName() : ""));
                sheet.addCell(new Label(col++, row, null != orderInfo ? orderInfo.getPostmanPhone() : ""));
                row++;     // 行
            }

            workbook.write();
            workbook.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return outputPath;
    }

    // 靠谱送v1.0 商家订单-批量导入-读取excel
    @RequestMapping(method = RequestMethod.POST, value = "/user/batch/order/excel/read")
    @ResponseBody
    public String order_excel_read(String token, FileUploadInfo info) {
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }
        try {
//            List<OtherOrderInfoVO> list = otherOrderService.readExcelFile(info.getFile());
            List<OtherOrderInfoVO> list = otherOrderService.readExcelFileV2(info.getFile(), user.getUsername());
            return AjaxResult.successResult(list.size(), list);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.errorResult(e.getLocalizedMessage());
        }
    }

    // 靠谱送v1.0 商家订单-批量导入-获取模板
    @RequestMapping(method = RequestMethod.POST, value = "/user/paotui/batch/order/excel/template")
    @ResponseBody
    public String order_excel_template() {
        if (ValidateUtil.isNull(SYS_CONFIG_PATH.PAOTUI_BATCH_ORDER_TEMPLATE)) {
            return AjaxResult.errorResult("未配置,请联系管理员");
        }
        File file = new File(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.PAOTUI_BATCH_ORDER_TEMPLATE);
        System.out.println(SYS_CONFIG_PATH.IMAGE_BASE_FILE + SYS_CONFIG_PATH.PAOTUI_BATCH_ORDER_TEMPLATE);
        if (!file.exists()) {
            return AjaxResult.errorResult("文件不存在");
        }
        String url = SYS_CONFIG_PATH.IMAGE_BASE_URL + SYS_CONFIG_PATH.PAOTUI_BATCH_ORDER_TEMPLATE;
        return AjaxResult.successResult(url);
    }

    /**
     * @param token
     * @return
     */
    // 靠谱送v1.0 商家订单-批量导入
    @RequestMapping(method = RequestMethod.POST, value = "/user/paotui/batch/order/save")
    @ResponseBody
    public String order_excel_batch(String token,
                                    String fromAddress, Double fromLat, Double fromLng,
                                    String fromProvince,
                                    String fromCity,
                                    String fromCounty,
                                    String fromUser,
                                    String fromPhone,
                                    String json) {
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }
        if (ValidateUtil.isNull(json)) {
            return AjaxResult.errorResult("导入信息不能为空");
        }
        if (ValidateUtil.isNull(fromCity) || ValidateUtil.isNull(fromAddress) || ValidateUtil.isNotLatLng(fromLat, fromLng) || ValidateUtil.isNull(fromPhone)) {
            return AjaxResult.errorResult("发货方信息不全");
        }
        try {
            otherOrderService.batchPaotuiOrder(fromAddress, fromLat, fromLng,
                    fromProvince,
                    fromCity,
                    fromCounty,
                    fromUser,
                    fromPhone, json, user.getUsername());
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.errorResult("导入失败:" + e.getMessage());
        }
        return AjaxResult.successResult();

    }


}
